/*
 * Component.java
 * Created on July 15, 2007, 8:29 PM
 */

package view;

import base.ResourceAccess;
import java.io.IOException;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import utils.Util;
import view.border.Border;
import view.font.Font;
import view.font.FontFactory;

/**
 * 
 * @author Erol Hira
 */
public abstract class Component implements Constants{
    
    public static final byte NONE = -1;
    public static final byte LEFT = 0;
    public static final byte CENTER = 1;
    public static final byte RIGHT = 2;
    
    protected int x;
    protected int y;
    protected int width;
    protected int height;
    
    // below four are inner margin values
    protected int marginLeft = 2;
    protected int marginRight = 2;
    protected int marginTop = 2;
    protected int marginBottom = 2;
    
    protected int outerMarginLeft = 2;
    protected int outerMarginRight = 2;
    protected int outerMarginTop = 2;
    protected int outerMarginBottom = 2;
    
    // for alignment inside the component
    protected int alignment = Graphics.LEFT | Graphics.VCENTER;
    
    protected int containerHorizontalAlignment = NONE;
    
    protected Color bgColor;
    protected Color fgColor;
    protected Font font;
    
    protected Border border;
    
    protected CommandListener commandListener;
    
    protected Image bgImage;
    
    protected boolean paintFlag;
    
    protected boolean visible = true;
    
    protected Container container;
    
    private KeyManager keyManager;
    
    private Constraints constraints; // layout constraints
    
    protected byte z_order = DEFAULT_Z_ORDER;
    
    protected boolean focusable;
    
    /**
     *  Default values are defined in this constructor 
     */
    public Component() {                 
        
        border = new Border();
        font = FontFactory.getDefaultFont();
        
        bgColor = Color.WHITE;
        fgColor = Color.BLACK;
        
        paintFlag = true;
        
        keyManager = new KeyManager(this);
        
        // must be the last line in this constructor
        // to use the above values in derived constructors.
        init();
    }
    
    public Component(int width, int height){
        
        this();
        this.width = width;
        this.height = height;
    }
    
    public Component(int x, int y, int width, int height){
        
        this(width, height);
        this.x = x;
        this.y = y;
    }
    
    //----------------------------------------------------------------------
    
    /**
     *  evaluated at the end of the non-param-constructor 
     */
    protected abstract void init();        
    
    public abstract void paint(Graphics g);
    
    public void onFocus(){}
    
    public void onFocusLost(){}
    
    //----------------------------------------------------------------------
    
    public void repaint(){
        
        if(container != null){
            
            paintFlag = true;
            container.repaintContainer();
        }        
    }
    
    public void paintComponent(Graphics g){
        
        if(readyToPaint() == false){
            System.out.println("paintFlag false : " + getClass().getName() + " returns");
            return;
        }
        
        initPaint();
        
        paintBorder(g);
        paintBG(g);
        paint(g);        
        
        paintFlag = false;
    }
    
    public void paintFocus(Graphics g){        
    }
    
    public void initPaint(){};
    
    protected void paintBG(Graphics g){
        
        // paint bg
        GuiUtils.setColor(g, bgColor);
        g.fillRect(get_x_content(), get_y_content(), width, height);
        
        if(bgImage == null){
            return;
        }
        
        g.drawImage(bgImage, get_x_content(), get_y_content(), Graphics.TOP | Graphics.LEFT);
    }
    
    protected void paintBorder(Graphics g){
        
        border.paint(g, this);
    }
    
    protected boolean readyToPaint(){
        return paintFlag == true && visible == true;
    }
    
    public void setContainerHorizontalAlignment(byte containerHorizontalAlignment){
        
        if(LEFT == containerHorizontalAlignment){
            x = outerMarginLeft;
        } else if(CENTER == containerHorizontalAlignment){
            x = (container.getWidth() / 2) - (getWholeWidth() / 2);
        } else if(RIGHT == containerHorizontalAlignment){
            x = container.getWidth() - (outerMarginRight + getWholeWidth());
        }
    }
    
    //----------------------------------------------------------------------
    
    public final void keyPressed(int keyCode) {
                                           
        keyManager.keyPressed(keyCode);         
    }
    
    
    protected void doUP(){
        container.focusPrevious();
    }
    
    protected void doDOWN(){
        container.focusNext();
    }
    
    protected void doRIGHT(){
        container.focusNext();
    }
    
    protected void doLEFT(){
        container.focusPrevious();
    }
    
    protected void doFire(){
        container.doFire();
    }
    
    protected void doKey(String ch){        
    }

    public Border getBorder() {
        return border;
    }
    
    //----------------------------------------------------------------------
    
    public int get_x_content(){
        return x + border.getW_left();
    }
    
    public int get_y_content(){
        return y + border.getW_top();
    }
    
    public int getWholeWidth(){
        return width + border.getW_left() + border.getW_right();
    }
    
    public int getWholeHeight(){
        return height + border.getW_top() + border.getW_bottom();
    }            
    
    public void setBorder(Border border){
        this.border = border;
    }
    
    public void setLocation(int x, int y){    
        setX(x);
        setY(y);
    }
    
    //----------------------------------------------------------------------
    
    /**
     *  sets the bgImage
     *  directly to the background of this component 
     */
    public void setBgImage(Image bgImage){
        this.bgImage = bgImage;
    }
    
    /**
     *  sets the bgImage
     *  directly to the background of this component 
     */
    public void setBgImage(String imgUrl){
        try {
            bgImage = Image.createImage(imgUrl);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
    
    public void removeBgImage(){
        bgImage = null;
    }
    
    public boolean isFocused(){
        return container.isFocused(this);
    }
    
    
    
    //----------------------------------------------------------------------
    
    public void setCommandListener(CommandListener commandListener){        
        this.commandListener = commandListener;
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

    public int getWidth() {
        return width;
    }

    public void setWidth(int width) {
        this.width = width;
    }

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }          
    
    public Font getFont() {
        return font;
    }

    public void setFont(Font font) {
        this.font = font;        
    }

    public Image getBgImage() {
        return bgImage;
    }        

    public Color getBgColor() {
        return bgColor;
    }

    public void setBgColor(Color bgColor) {
        this.bgColor = bgColor;
    }

    public Color getFgColor() {
        return fgColor;
    }

    public void setFgColor(Color fgColor) {
        this.fgColor = fgColor;
    }        

    public void setContainer(Container container) {
        this.container = container;
    }

    public Container getContainer() {
        return container;
    }

    public int getMarginLeft() {
        return marginLeft;
    }

    public void setMarginLeft(int marginLeft) {
        this.marginLeft = marginLeft;
    }

    public int getMarginRight() {
        return marginRight;
    }

    public void setMarginRight(int marginRight) {
        this.marginRight = marginRight;
    }

    public int getMarginTop() {
        return marginTop;
    }

    public void setMarginTop(int marginTop) {
        this.marginTop = marginTop;
    }

    public int getMarginBottom() {
        return marginBottom;
    }

    public void setMarginBottom(int marginBottom) {
        this.marginBottom = marginBottom;
    }

    public Constraints getConstraints() {
        return constraints;
    }

    public void setConstraints(Constraints constraints) {
        this.constraints = constraints;
    }

    public byte getZ_order() {
        return z_order;
    }

    public void setZ_order(byte z_order) {
        this.z_order = z_order;
    }

    public void setAlignment(int alignment) {
        this.alignment = alignment;
    }

    public boolean isFocusable() {
        return focusable;
    }

    public boolean isPaintFlag() {
        return paintFlag;
    }

    public void setPaintFlag(boolean paintFlag) {
        this.paintFlag = paintFlag;
    }

    public boolean isVisible() {
        return visible;
    }

    public void setVisible(boolean visible) {
        this.visible = visible;
    }
    
    //---------------------------------------------------------------------
    
    public void setProperty(int property, String value){
        
        if(Fields.X == property){
            
            x = Integer.parseInt(value);
            
        } else if(Fields.Y == property){
        
            y = Integer.parseInt(value);
            
        } else if(Fields.WIDTH == property){
            
            width = Integer.parseInt(value);
            
        } else if(Fields.HEIGHT == property){
            
            height = Integer.parseInt(value);
            
        } else if(Fields.MARGIN_LEFT == property){
            
            marginLeft = Integer.parseInt(value);
            
        } else if(Fields.MARGIN_RIGHT == property){
            
            marginRight = Integer.parseInt(value);
            
        } else if(Fields.MARGIN_TOP == property){
        
            marginTop = Integer.parseInt(value);
            
        } else if(Fields.MARGIN_BOTTOM == property){
            
            marginBottom = Integer.parseInt(value);
            
        } else if(Fields.OUTER_MARGIN_LEFT == property){
            
            outerMarginLeft = Integer.parseInt(value);
            
        } else if(Fields.OUTER_MARGIN_RIGHT == property){
            
            outerMarginRight = Integer.parseInt(value);
            
        } else if(Fields.OUTER_MARGIN_TOP == property){
            
            outerMarginTop = Integer.parseInt(value);
            
        } else if(Fields.OUTER_MARGIN_BOTTOM == property){
            
            outerMarginBottom = Integer.parseInt(value);
            
        } else if(Fields.ALIGNMENT == property){
            
            alignment = Integer.parseInt(value);
            
        } else if(Fields.CONTAINER_HORIZONTAL_ALIGNMENT == property){
            
            containerHorizontalAlignment = Integer.parseInt(value);
            
        } else if(Fields.BG_COLOR == property){
            
            bgColor = GuiUtils.getColor(value);
            
        } else if(Fields.FG_COLOR == property){
            
            fgColor = GuiUtils.getColor(value);
            
        } else if(Fields.FONT == property){
            
            font = ResourceAccess.getFont(Integer.parseInt(value));
            
        } else if(Fields.BORDER == property){
            
            border = ResourceAccess.getBorder(Integer.parseInt(value));
            
        } else if(Fields.BG_IMAGE == property){
        
            bgImage = ResourceAccess.getImage(Integer.parseInt(value));
            
        } else if(Fields.PAINT_FLAG == property){
            
            paintFlag = Util.booleanValue(value);
            
        } else if(Fields.VISIBLE == property){
            
            visible = Util.booleanValue(value);
            
        } else if(Fields.Z_ORDER == property){
            
            z_order = (byte) Integer.parseInt(value);
            
        } else {
            
            setHighLevelProperty(property, value);
        }
    }
    
    protected void setHighLevelProperty(int property, String value){
    }
    
}
